<template>
  <div style="width: 100%">
    <!-- 输入区域 -->
    <el-input
      v-model="selectedAddress"
      type="textarea"
      :rows="3"
      placeholder="已选位置"
      readonly
      style="width: 100%"
    />
    <el-button @click="showMapDialog" class="mt-2">选择位置</el-button>

    <!-- 地图弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      title="位置选择"
      width="60%"
      height="80%"
      @closed="destroyMap"
    >
      <div class="map-container">
        <!-- 搜索栏 -->
        <el-autocomplete
          v-model="searchText"
          placeholder="输入地址搜索"
          :fetch-suggestions="querySearch"
          @select="handleSelect"
          clearable
          class="mb-1"
        />

        <!-- 提示信息 -->
        <div class="map-wrapper" v-if="loading">地图正在初始化中......</div>

        <!-- 地图容器 -->
        <div id="amap-container" ref="aMapContainer" class="map-wrapper"></div>

        <!-- 位置信息 -->
        <div class="position-info">
          <el-descriptions :column="1" border>
            <el-descriptions-item label="地址" label-width="120px">
              {{ currentPosition.address }}
            </el-descriptions-item>
            <el-descriptions-item label="经度" label-width="120px">
              {{ currentPosition.lng }}
            </el-descriptions-item>
            <el-descriptions-item label="纬度" label-width="120px">
              {{ currentPosition.lat }}
            </el-descriptions-item>
          </el-descriptions>
        </div>
      </div>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmSelection">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
/**
 * 高德位置选择器
 * 坐标格式：GCJ02
 * 配置选项：securityJsCode，key
 * 展示组件：ra-view-amap
 * 坐标转换：推荐 gcoord (系统已经集成)
 */
import gcoord from 'gcoord';
import AMapLoader from '@amap/amap-jsapi-loader';
import { ElMessageBox } from 'element-plus';
import { ref, reactive, watch, nextTick } from 'vue'; // 确保所有 Vue API 都已导入

const securityJsCode = import.meta.env.VITE_APP_MAP_AMAP_SECRET; // 高德密钥
const key = import.meta.env.VITE_APP_MAP_AMAP_KEY; // 高德密钥

const zoom = 16;
const loading = ref(false);

const dialogVisible = ref(false);
const searchText = ref('');
const selectedAddress = ref(''); // 用于显示在输入框中的地址文本
const mapInstance = ref(null);
const markerInstance = ref(null); // *** 用于管理唯一的标记实例 ***
const currentPosition = reactive({
  address: '',
  lng: null,
  lat: null,
});

let autoCompleteInstance = null;
let geocoderInstance = null; // *** 用于管理地理编码器实例 ***

// 安全密钥配置
window._AMapSecurityConfig = {
  securityJsCode: securityJsCode,
};

// *** 定义 props 和 emits ***
const props = defineProps({
  modelValue: {
    type: [Object, String], // 允许 modelValue 是对象或字符串
    default: null,
  },
});

const emit = defineEmits(['update:modelValue']);

// *** 添加 watch 监听器以实现数据回显 ***
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal) {
      try {
        const parsedValue =
          typeof newVal === 'string' ? JSON.parse(newVal) : newVal;
        if (parsedValue && parsedValue.address) {
          selectedAddress.value = parsedValue.address; // 只显示地址
          // 同步内部状态
          currentPosition.address = parsedValue.address;
          currentPosition.lng = parsedValue.lng;
          currentPosition.lat = parsedValue.lat;
        } else {
          selectedAddress.value = '';
        }
      } catch (e) {
        console.error('解析 modelValue 失败:', e);
        selectedAddress.value = '';
      }
    } else {
      selectedAddress.value = '';
    }
  },
  { immediate: true, deep: true },
);

// *** 改进地图初始化逻辑 ***
const initMap = async () => {
  try {
    loading.value = true;
    if (!securityJsCode || !key) {
      ElMessageBox.alert('请先配置高德地图的key和securityJsCode', '提示');
      loading.value = false;
      return;
    }

    const AMap = await AMapLoader.load({
      key: key,
      version: '2.0',
      plugins: [
        'AMap.PlaceSearch',
        'AMap.Geolocation',
        'AMap.Geocoder',
        'AMap.AutoComplete',
      ],
    });

    let initialPoint;

    // 如果有已保存的坐标，则使用它
    if (currentPosition.lng && currentPosition.lat) {
      initialPoint = [currentPosition.lng, currentPosition.lat];
    } else {
      // 否则，获取当前GPS位置并转换
      const gpsPosition = await getGPSLocation();
      const position = convertLocation(gpsPosition);
      initialPoint = [position.lng, position.lat];
    }

    mapInstance.value = new AMap.Map('amap-container', {
      center: initialPoint,
      zoom: zoom,
      viewMode: '2D',
    });

    // 初始化地理编码和自动完成实例
    geocoderInstance = new AMap.Geocoder();
    autoCompleteInstance = new AMap.AutoComplete({ city: '全国' });

    // 更新标记和地址信息
    updateMarkerAndAddress(initialPoint);

    mapInstance.value.on('click', (e) => {
      const point = [e.lnglat.getLng(), e.lnglat.getLat()];
      updateMarkerAndAddress(point);
    });

    loading.value = false;
  } catch (error) {
    loading.value = false;
    console.error('地图加载失败:', error);
  }
};

// 搜索建议
const querySearch = (queryString, cb) => {
  if (!queryString || !autoCompleteInstance) return cb([]);
  autoCompleteInstance.search(queryString, (status, result) => {
    if (status === 'complete' && result.tips) {
      const suggestions = result.tips
        .filter((tip) => tip.location)
        .map((tip) => ({
          value: `${tip.name}（${tip.district}${tip.address}）`,
          ...tip,
          lng: tip.location.lng,
          lat: tip.location.lat,
        }));
      cb(suggestions);
    } else {
      cb([]);
    }
  });
};

// 处理选择建议
const handleSelect = (item) => {
  searchText.value = item.value;
  const point = [item.lng, item.lat];
  mapInstance.value.setCenter(point);
  mapInstance.value.setZoom(zoom);
  updateMarkerAndAddress(point);
};

// *** 封装更新标记和地址的函数 ***
const updateMarkerAndAddress = (point) => {
  // 更新内部位置状态
  currentPosition.lng = point[0];
  currentPosition.lat = point[1];

  // 更新标记
  if (markerInstance.value) {
    markerInstance.value.setPosition(point);
  } else {
    markerInstance.value = new AMap.Marker({
      position: point,
      map: mapInstance.value,
    });
  }

  // 反向地理编码获取地址
  geocoderInstance.getAddress(point, (status, result) => {
    if (status === 'complete' && result.regeocode) {
      currentPosition.address = result.regeocode.formattedAddress;
    } else {
      console.error('逆向地理编码失败');
    }
  });
};

// 显示弹窗
const showMapDialog = () => {
  dialogVisible.value = true;
  nextTick(() => {
    // 确保在初始化新地图前，任何旧的实例都已被销毁
    if (mapInstance.value) {
      mapInstance.value.destroy();
      mapInstance.value = null;
    }
    // 强制重新初始化地图
    initMap();
  });
};

// 销毁地图
const destroyMap = () => {
  if (mapInstance.value) {
    mapInstance.value.destroy();
    mapInstance.value = null;
    markerInstance.value = null;
    geocoderInstance = null;
    autoCompleteInstance = null;
  }
  // 不重置 currentPosition，以便下次打开时能恢复
};

// *** 确认选择时的数据处理 ***
const confirmSelection = () => {
  const addressData = {
    address: currentPosition.address,
    lat: currentPosition.lat,
    lng: currentPosition.lng,
  };
  // 更新输入框的显示值
  selectedAddress.value = addressData.address;
  // 向上层组件发出一个 JSON 字符串
  emit('update:modelValue', JSON.stringify(addressData));
  dialogVisible.value = false;
};

// 根据浏览器获得GPS坐标
const getGPSLocation = () => {
  return new Promise((resolve) => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          resolve({
            lat: position.coords.latitude,
            lng: position.coords.longitude,
          });
        },
        () => {
          resolve({ lat: 39.90923, lng: 116.397428 }); // 定位失败默认北京天安门
        },
      );
    } else {
      resolve({ lat: 39.90923, lng: 116.397428 }); // 不支持则默认北京
    }
  });
};

// 坐标转换
const convertLocation = (point) => {
  const result = gcoord.transform(
    [point.lng, point.lat],
    gcoord.WGS84,
    gcoord.GCJ02,
  );
  return { lng: result[0], lat: result[1] };
};
</script>

<style lang="scss" scoped>
.map-container {
  height: 60vh;
}

.map-wrapper {
  height: 400px;
  width: 100%;
  margin: 16px 0;
}

.suggest-list {
  position: absolute;
  z-index: 1;
  background-color: #fff;
  width: calc(100% - 40px);
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  margin-top: 5px;

  li {
    padding: 10px;
    cursor: pointer;
    transition: background 0.3s;

    &:hover {
      background: #f5f7fa;
    }
  }
}

.position-info {
  margin-top: 16px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
}

.dialog-footer {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>
